package com.crimax.lanproj.properties;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

public class LoanPropertiesHolder {

	
	ResourceBundle credits = ResourceBundle.getBundle("lan"); 
	private final String propertyNumberOfSuppliers  = "numberOfSuppliers";
	static LoanPropertiesHolder loanPropertiesHolder;
	private List<LoanProperties> smallLoanProperties = new ArrayList<LoanProperties>();
	private List<LoanProperties> bigLoanProperties = new ArrayList<LoanProperties>();
	
	private final static int DAYS30 = 30;
	private final static int DAYS60 = 60;
	private final static int DAYS90 = 90;
	
	private int smallLoanSortCach=0;
	private int bigLoanSortCach=0;
	
	public static LoanPropertiesHolder getSingletonObject() {
			if (loanPropertiesHolder == null) {
				loanPropertiesHolder = new LoanPropertiesHolder();
			}
			return loanPropertiesHolder;
		}

	public LoanPropertiesHolder() {
		super();
		this.smallLoanProperties = this.loadProperty();
		
	}
	
	public List<LoanProperties> getLoanProperties(){
		return this.smallLoanProperties;
	}
	
	
	private List<LoanProperties> loadProperty(){
		int numberOfSuppliers = new Integer(credits.getString(propertyNumberOfSuppliers));
		int propertyRow=1;
		
		ArrayList<LoanProperties> unSortedSupplierList = new ArrayList<LoanProperties>();
		ArrayList<LoanProperties> unSortedBigSupplierList = new ArrayList<LoanProperties>();
		
		while (numberOfSuppliers>=propertyRow) {
			
			LoanProperties loanProperties = new LoanProperties();
			loanProperties.setBank(credits.getString(LoanPropertyTypes.BANK.getType(propertyRow)));
			loanProperties.setName(credits.getString(LoanPropertyTypes.NAME.getType(propertyRow)));
			loanProperties.setFriendlyName(credits.getString(LoanPropertyTypes.FRIENDLY_NAME.getType(propertyRow)));
			loanProperties.setWeekendPayment(credits.getString(LoanPropertyTypes.WEEKEND_PAYMENT.getType(propertyRow)));
			loanProperties.setURL(credits.getString(LoanPropertyTypes.URL.getType(propertyRow)));
			loanProperties.setImageSource(credits.getString(LoanPropertyTypes.IMAGE_SRC.getType(propertyRow)));
			
			loanProperties.setAge(credits.getString(LoanPropertyTypes.AGE.getType(propertyRow)));
			loanProperties.setBa(credits.getString(LoanPropertyTypes.BA.getType(propertyRow)));
			loanProperties.setEleg(credits.getString(LoanPropertyTypes.ELEG.getType(propertyRow)));
			loanProperties.setEpost(credits.getString(LoanPropertyTypes.EPOST.getType(propertyRow)));
			loanProperties.setUc(credits.getString(LoanPropertyTypes.UC.getType(propertyRow)));
			loanProperties.setFreeAmount(credits.getString(LoanPropertyTypes.FREE_AMOUNT.getType(propertyRow)));
			loanProperties.setFreeTime(credits.getString(LoanPropertyTypes.FREE_TIME.getType(propertyRow)));
			
			try{
				loanProperties.setMinSize(new Integer(credits.getString(LoanPropertyTypes.MIN_SIZE.getType(propertyRow))));
				loanProperties.setMaxSize( new Integer (credits.getString(LoanPropertyTypes.MAX_SIZE.getType(propertyRow))));
				loanProperties.setInterest(new Float(credits.getString(LoanPropertyTypes.INTEREST.getType(propertyRow))));
			}catch(MissingResourceException e){
				//"it's ok, you can dance now
			}
			
			try{
				loanProperties.setMaxYear(new Integer(credits.getString(LoanPropertyTypes.MAX_YEAR.getType(propertyRow))));
				loanProperties.setMinYear( new Integer (credits.getString(LoanPropertyTypes.MIN_YEAR.getType(propertyRow))));
			}catch(MissingResourceException e){
				//"it's ok, you can dance now"
			}
			
			String unParsedPrices30 = credits.getString(LoanPropertyTypes.AMOUNT30.getType(propertyRow));
			loanProperties.getPrice30().addAll(this.mapObjectsFromPropString(unParsedPrices30));
			
			String unParsedPrices60 = credits.getString(LoanPropertyTypes.AMOUNT60.getType(propertyRow));
			loanProperties.getPrice60().addAll(this.mapObjectsFromPropString(unParsedPrices60));
			
			String unParsedPrices90 = credits.getString(LoanPropertyTypes.AMOUNT90.getType(propertyRow));
			loanProperties.getPrice90().addAll(this.mapObjectsFromPropString(unParsedPrices90));
			
			if(unParsedPrices30.isEmpty()&&unParsedPrices60.isEmpty()&&unParsedPrices90.isEmpty()){
				
			}else{
				unSortedSupplierList.add(loanProperties);
			}
			
			if(loanProperties.getInterest()!=0){
				unSortedBigSupplierList.add(loanProperties);
			}
			propertyRow++;
		}
		
		
		this.smallLoanProperties=unSortedSupplierList;
		this.bigLoanProperties=unSortedBigSupplierList;
//		List<LoanProperties> sortedList = this.getSortSupplierByLoanSize( 4000, 30);
//		
//		for (LoanProperties loanProperties : sortedList) {
//			
//			
//			
//			List<PriceObject> price30 = loanProperties.getPrice30();
//			
//			
//			for (PriceObject priceObject : price30) {
//				System.out.println(priceObject.getFee());
//				priceObject.getAmount();
//				if(priceObject.getAmount()==4000)
//				System.out.println(loanProperties.getName()+"    "+priceObject.getFee());
//			}
//		}
//		
		return unSortedSupplierList;
		
	}
	
	private List<PriceObject> mapObjectsFromPropString(String unParsedPrices){
		
		String[] splited = unParsedPrices.split(",");
		
		List<PriceObject> priceObjects = new ArrayList<PriceObject>();

		for (String priceString : splited) {
			if(priceString.isEmpty()){
				
			}else{
		
				String[] splitedPrice = priceString.split(":");
				String loanSize = splitedPrice[0];
				String loanFee = splitedPrice[1];
				if(!loanFee.isEmpty() && !loanSize.isEmpty() )
				priceObjects.add(new PriceObject(new Integer(loanSize), new Integer(loanFee)));
			}
		}
		
		return priceObjects; 
	}
	
	public List<LoanProperties> getbigLoanSortSupplierByLoanSize(){
		
		
		if(1==bigLoanSortCach){

			return this.bigLoanProperties;
		}

		Comparator<LoanProperties> comparator = new Comparator<LoanProperties>() {

			@Override
			public int compare(LoanProperties loanProperties1, LoanProperties loanProperties2 ) {
				
				final int AFTER = -1;
				final int EQUAL = 0;
				final int BEFORE = 1;
				
				float price1 = loanProperties1.getInterest();
				float price2 = loanProperties2.getInterest();
				
				if(price2 ==0 && price1==0){
					return EQUAL;
				}
				if(price2==0 || price1 == 0){
					if(price1 == 0){
						return BEFORE;
					}
					if(price2 == 0){
						return AFTER;
					}
				}
				
				if(price2<price1){
					return BEFORE;
				}
				if(price2>price1){
					return AFTER;
				}
				if(price2==price1){
					return EQUAL;
				}
				
				throw new IllegalStateException("This should be unreachable!");
			}
		};
		
		this.bigLoanSortCach = 1;
		Collections.sort(this.bigLoanProperties, comparator);
		
		return this.bigLoanProperties;
	}
	
public List<LoanProperties> getSortSupplierByLoanSize( final int loanSize, final int loanLength){
		
		
		if((loanSize+loanLength)==smallLoanSortCach){

			return this.smallLoanProperties;
		}

		Comparator<LoanProperties> comparator = new Comparator<LoanProperties>() {

			@Override
			public int compare(LoanProperties loanProperties1, LoanProperties loanProperties2 ) {
				
				final int AFTER = -1;
				final int EQUAL = 0;
				final int BEFORE = 1;
				
				PriceObject price1 = getComparatorValue(loanProperties1, loanSize, loanLength);
				PriceObject price2 = getComparatorValue(loanProperties2, loanSize, loanLength);
				
				if(price2 ==null && price1==null){
					return EQUAL;
				}
				if(price2==null || price1 == null){
					if(price1 == null){
						return BEFORE;
					}
					if(price2 == null){
						return AFTER;
					}
				}
				
				if(price2.getFee()<price1.getFee()){
					return BEFORE;
				}
				if(price2.getFee()>price1.getFee()){
					return AFTER;
				}
				if(price2.getFee()==price1.getFee()){
					return EQUAL;
				}
				
				throw new IllegalStateException("This should be unreachable!");
			}
		};
		
		this.smallLoanSortCach = loanLength+loanSize;
		Collections.sort(this.smallLoanProperties, comparator);
		
		return this.smallLoanProperties;
	}

	public List<NameHolder> getSmallLoanNamesInNaturalOrder(){
		
		Comparator<LoanProperties> comparator = new Comparator<LoanProperties>() {

			@Override
			public int compare(LoanProperties loanProperties1, LoanProperties loanProperties2 ) {
				
				 return loanProperties1.getName().compareTo(loanProperties2.getName());
			}
		};
		
		Collections.sort(this.smallLoanProperties, comparator);
		
		List<NameHolder> names = new ArrayList<NameHolder>(smallLoanProperties.size());
		
		for (int i = 0; i < smallLoanProperties.size(); i++) {
			NameHolder nameHolder = new NameHolder( smallLoanProperties.get(i).getName(),  smallLoanProperties.get(i).getFriendlyName());
			names.add(i ,nameHolder);
		}
		
		return names;
	}
	
	public List<LoanProperties> getFreeAmountPoperties(){

		ArrayList<LoanProperties> tempList = new ArrayList<LoanProperties>();
		for (LoanProperties loan : smallLoanProperties) {
			if(loan.getFreeAmount()!=null && !loan.getFreeAmount().isEmpty()){
				tempList.add(loan);
			}
		}
		
		return tempList;
		
	}
	
	public List<NameHolder> getBigLoanNamesInNaturalOrder(){
		
		Comparator<LoanProperties> comparator = new Comparator<LoanProperties>() {

			@Override
			public int compare(LoanProperties loanProperties1, LoanProperties loanProperties2 ) {
				
				 return loanProperties1.getName().compareTo(loanProperties2.getName());
			}
		};
		
		Collections.sort(this.bigLoanProperties, comparator);
		
		List<NameHolder> names = new ArrayList<NameHolder>(bigLoanProperties.size());
		
		for (int i = 0; i < bigLoanProperties.size(); i++) {
			NameHolder nameHolder = new NameHolder( bigLoanProperties.get(i).getName(),  bigLoanProperties.get(i).getFriendlyName());
			names.add(i ,nameHolder);
		}
		
		return names;
	}
	
	private PriceObject getComparatorValue(LoanProperties loanProperties,final int loanSize, final int loanLength){
		
			
			List<PriceObject> priceObjects = null;
			
			if(loanLength==DAYS30){
				priceObjects = loanProperties.getPrice30();
			}
			if(loanLength==DAYS60){
				priceObjects = loanProperties.getPrice60();
			}
			if(loanLength==DAYS90){
				priceObjects = loanProperties.getPrice90();
			}
			
			if(priceObjects == null){
				return null;
			}
			
			for (PriceObject priceObject : priceObjects) {
				
				if(priceObject.getAmount() == loanSize){
					return priceObject;
				}
			}
			return null;
	}
	
}
